home *** CD-ROM | disk | FTP | other *** search
- /* Copyright 1990 by Christopher A. Wichura.
- See file GIFMachine.doc for full description of rights.
- */
-
- #include "GIFMachine.h"
-
- extern struct GIFdescriptor gdesc;
- EXTERNBITPLANE;
-
- extern char *AbortMsg;
-
- extern BOOL DisplayCounts;
-
- extern BOOL Laced;
-
- UWORD *SHAMmem;
-
- struct RGB Palette[16];
-
- extern UBYTE PaletteBuf[MAXCOLOURS];
- extern ULONG ColourBuf[MAXCOLOURS];
- static ULONG ErrBuf[MAXCOLOURS];
-
- #define ISLACED (Laced && (y != gdesc.gd_Height - 1))
-
- void GIFtoSHAM(void)
- {
- register UWORD x;
- register UWORD current;
- register int index;
- register int index2;
- ULONG error;
- UWORD y;
- int Pal;
- int ShamIndex;
- int colours;
-
- ULONG TotalErr, LineErr;
-
- ULONG bestpal;
- ULONG besterr;
-
- UBYTE CurrentRed, CurrentGreen, CurrentBlue;
- UBYTE PreviousRed, PreviousGreen, PreviousBlue;
-
- MyPrintf("...Converting to SHAM format.\n......");
- if (DisplayCounts)
- PutStr("Line");
- else
- PutStr("Working");
- Flush(Output());
-
- ShamIndex = TotalErr = 0;
-
- /* palette zero is always the background colour. regardless of
- what the GIF specified for the background, we always use black.
- this is a kludge to get around a hardware `feature' that causes
- all overscanned screens to have a black background regardless
- of what the background was specified to be.
- */
-
- Palette[0].rgb_Red = Palette[0].rgb_Green = Palette[0].rgb_Blue = 0;
-
- for (y = 0; y < gdesc.gd_Height; y += (ISLACED ? 2 : 1)) {
- if (DisplayCounts) {
- if (ISLACED)
- MyPrintf("s %5ld-%5ld", y, y + 1);
- else
- MyPrintf(" %5ld", y);
- }
-
- if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
- MyPrintf("\n%s", AbortMsg);
- MyExit(ABORTEXITVAL);
- }
-
- memset((char *)ColourBuf, 0, sizeof(ColourBuf));
-
- for (colours = index2 = 0; index2 < (ISLACED ? 2 : 1); index2++)
- for (x = 0; x < gdesc.gd_Width; x++) {
- current = GetValue(x, y + index2);
-
- if (ColourBuf[current]++ == 0)
- colours++;
- }
-
- if (DisplayCounts)
- MyPrintf(", %4ld unique colours", colours);
-
- memset((char *)PaletteBuf, 0, sizeof(PaletteBuf));
-
- for (index = 0; index < MAXCOLOURS; index++) {
- if (ColourBuf[index] == 0)
- continue;
-
- ErrBuf[index] = RGBdiff(GetRed(index),
- GetGreen(index),
- GetBlue(index),
- Palette[0].rgb_Red,
- Palette[0].rgb_Green,
- Palette[0].rgb_Blue);
- }
-
- for (Pal = 1; Pal < 16; Pal++) {
- for (besterr = index = 0; index < MAXCOLOURS; index++) {
- if (ColourBuf[index] == 0)
- continue;
-
- if (ErrBuf[index] * ColourBuf[index] >= besterr) {
- bestpal = index;
- besterr = ErrBuf[index] * ColourBuf[index];
- }
- }
-
- Palette[Pal].rgb_Red = GetRed(bestpal);
- Palette[Pal].rgb_Green = GetGreen(bestpal);
- Palette[Pal].rgb_Blue = GetBlue(bestpal);
-
- for (index = 0; index < MAXCOLOURS; index++) {
- if (ColourBuf[index] == 0)
- continue;
-
- error = RGBdiff(GetRed(index),
- GetGreen(index),
- GetBlue(index),
- Palette[Pal].rgb_Red,
- Palette[Pal].rgb_Green,
- Palette[Pal].rgb_Blue);
-
- if (error < ErrBuf[index]) {
- ErrBuf[index] = error;
- PaletteBuf[index] = Pal;
- }
- }
- }
-
- for (index = 0; index < 16; index++)
- SHAMmem[ShamIndex++] = (UWORD)(
- Palette[index].rgb_Red << 8 |
- Palette[index].rgb_Green << 4 |
- Palette[index].rgb_Blue);
-
- for (index2 = 0; index2 < (ISLACED ? 2 : 1); index2++) {
- PreviousRed = Palette[0].rgb_Red;
- PreviousGreen = Palette[0].rgb_Green;
- PreviousBlue = Palette[0].rgb_Blue;
-
- for (LineErr = x = 0; x < gdesc.gd_Width; x++) {
- current = GetValue(x, y + index2);
-
- CurrentRed = GetRed(current);
- CurrentGreen = GetGreen(current);
- CurrentBlue = GetBlue(current);
-
- besterr = ErrBuf[current];
- bestpal = PaletteBuf[current];
-
- error = RGBdiff(
- CurrentRed,
- CurrentGreen,
- CurrentBlue,
- CurrentRed,
- PreviousGreen,
- PreviousBlue);
-
- if (error < besterr) {
- besterr = error;
- bestpal = 16;
- }
-
- error = RGBdiff(
- CurrentRed,
- CurrentGreen,
- CurrentBlue,
- PreviousRed,
- CurrentGreen,
- PreviousBlue);
-
- if (error < besterr) {
- besterr = error;
- bestpal = 17;
- }
-
- error = RGBdiff(
- CurrentRed,
- CurrentGreen,
- CurrentBlue,
- PreviousRed,
- PreviousGreen,
- CurrentBlue);
-
- if (error < besterr) {
- besterr = error;
- bestpal = 18;
- }
-
- if (bestpal < 16) {
- PutValue(x, y + index2, bestpal);
-
- PreviousRed = Palette[bestpal].rgb_Red;
- PreviousGreen = Palette[bestpal].rgb_Green;
- PreviousBlue = Palette[bestpal].rgb_Blue;
- } else if (bestpal == 16) {
- PutValue(x, y + index2, CurrentRed | 0x20);
-
- PreviousRed = CurrentRed;
- } else if (bestpal == 17) {
- PutValue(x, y + index2, CurrentGreen | 0x30);
-
- PreviousGreen = CurrentGreen;
- } else {
- PutValue(x, y + index2, CurrentBlue | 0x10);
-
- PreviousBlue = CurrentBlue;
- }
-
- LineErr += besterr;
- }
-
- TotalErr += LineErr;
- }
-
- if (DisplayCounts)
- MyPrintf("\x1B[%sD\x1B[K", (ISLACED ? "34" : "27"));
- }
-
- {
- ULONG ErrPerPixel;
- char TextBuf[10];
-
- ErrPerPixel = ((TotalErr / gdesc.gd_Height) * 1000) / gdesc.gd_Width;
- MySPrintf(TextBuf, "%ld.%03ld", ErrPerPixel / 1000, ErrPerPixel % 1000);
-
- MyPrintf("\x1B[%ldDTotal colour error = %ld, Mean per line = %ld, Per pixel = %s.\n",
- (DisplayCounts ? 4 : 7), TotalErr, TotalErr / gdesc.gd_Height, TextBuf);
- }
- }
-